

import Database from "@tauri-apps/plugin-sql";

import { homePath, createDirs, getG01DataBase } from '../../utils';

import { metaDataGetMetaDataObjects, metaDataGetMetaDomain } from '../meta-data';

export interface DataSource {
    id: number;
    identifier: string;
    name: string;
    title: string;
    icon?: string;
    domain_identifiers: string;
    storage_type: string;
    storage_options: string;
    description?: string;
}

export const dataSourceGetDataSources = async (page: number, pageSize: number, keywords?: string): Promise<{ total: number, data: Array<DataSource> }> => {
    const db = await getG01DataBase();

    let offset = (page - 1) * pageSize;

    let conditions = ` `;
    let args = [];
    if (keywords && keywords != '') {
        conditions = ` where name like $1 `;
        args = [`%${keywords}%`];
    }

    let count = (await db.select(`select count(1) cnt from _g01_meta_datasources ${conditions}`, args))[0].cnt;
    //
    let items: Array<any> = await db.select(`select * from _g01_meta_datasources ${conditions} order by id desc limit ${offset},${pageSize} `, args);
    if (items) {
        return {
            total: count,
            data: items.map((item) => db2object(item)),
        };
    }
    return {
        total: 0,
        data: []
    };
}


export const dataSourceSaveDataSource = async (obj: DataSource): Promise<number> => {
    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    if (obj.id > 0) {
        await db.execute(`update _g01_meta_datasources set name = $2, icon = $3, storage_type = $4, storage_options = $5, description = $6 where identifier = $1`,
            [obj.identifier, obj.name, obj.icon, obj.storage_type, obj.storage_options, obj.description]);
        return 0;
    } else {
        await db.execute(`insert into _g01_meta_datasources(identifier,name,icon,domain_identifiers,storage_type,storage_options,description)Values($1,$2,$3,$4,$5,$6,$7)`,
            [obj.identifier, obj.name, obj.icon, domainIdentifiersToString(obj.domain_identifiers), obj.storage_type, obj.storage_options, obj.description]);

        let res: Array<any> = await db.select('SELECT last_insert_rowid() nid');
        console.log(res);
        if (res && res.length > 0) {
            return res[0].nid;
        }
        return 0;
    }
}

export const dataSourceUpdateDataSource = async (obj: DataSource): Promise<number> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    await db.execute(`update _g01_meta_datasources set name = $2, icon = $3, storage_type = $4, storage_options = $5, description = $6 where identifier = $1`,
        [obj.identifier, obj.name, obj.icon, obj.storage_type, obj.storage_options, obj.description]);
    return 0;
}


export const dataSourceUpdateDataSourceConfig = async (identifier: string, domains: Array<string>): Promise<number> => {

    // _g01_meta_class_attributes
    const db = await getG01DataBase();
    //
    await db.execute(`update _g01_meta_datasources set domain_identifiers = $2 where identifier = $1`,
        [identifier, domainIdentifiersToString(domains)]);
    return 0;
}

//
export const dataSourceDeleteDataSource = async (identifier: string): Promise<boolean> => {
    const db = await getG01DataBase();
    //
    //

    await db.execute(`delete from _g01_meta_datasources where identifier = '${identifier}' `);
    return true;
}

export const dataSourceGetObjectTree = async <T extends { children: T[] }>(dataSource: DataSource, convertFunc: (item: any) => T): Promise<Array<T>> => {
    const db = await getG01DataBase();

    let list: Array<T> = [];

    //循环相关的所有的domain
    for (let i = 0; i < dataSource.domain_identifiers.length; i++) {
        let domainIdentifier = dataSource.domain_identifiers[i];
        //
        let domain = await metaDataGetMetaDomain(domainIdentifier);
        if (!domain) {
            continue;
        }
        //获取所有的对象
        let { total, data: objects } = await metaDataGetMetaDataObjects(domainIdentifier, 1, 1000);
        //查询 data_is_type 
        let children = [];
        for (let j = 0; j < objects.length; j++) {
            //
            let obj = objects[j];
            let o = convertFunc(obj);
            children.push(o);
        }
        let d = convertFunc(domain);
        d.children = children;
        list.push(d);
    }

    return list;
}


export const dataSourceGetMappingSQL = async (dataSource: DataSource, objectIdentifier: string): Promise<string | null> => {
    const db = await getG01DataBase();

    let items: Array<any> = await db.select(`select * from data_data_source_mapping_sql where data_source_id = $1 and object_identifier = $2 order by id desc`, [dataSource.id, objectIdentifier]);
    console.log(items);
    if (items && items.length > 0) {
        return items[0].object_sql;
    }
    return null;
}


const db2object = (dbItem: any): DataSource => {
    if (!dbItem) {
        return dbItem;
    }
    let domains: Array<string> = [];
    if (dbItem && dbItem.domain_identifiers) {
        domains = dbItem.domain_identifiers.split(',').filter(item => item != '');
    }
    dbItem.domain_identifiers = domains;
    return dbItem;
}

const domainIdentifiersToString = (identifiers: Array<string>): string => {
    if (!identifiers || identifiers.length <= 0) {
        return '';
    }
    return identifiers.join(',');
}